import time
import threading
from motor.utils.singleton import ThreadSafeSingleton
from motor.coordinator.metrics.metrics import Metrics
from motor.config.coordinator import CoordinatorConfig

class MetricsListener(ThreadSafeSingleton):
    def __init__(self):
        self.reuse_time: int = CoordinatorConfig().prometheus_metrics_config.reuse_time
        self.last_call_time: int = 0
        self.last_metrics: dict = {
            "metrics": None,
            "instance_metrics": None
        }
        self.lock = threading.Lock()
        self.metrics_update_thread = threading.Thread(
            target=self.update_metrics,
            daemon=True,
            name="MetricsUpdate"
        )
        self.metrics_update_thread.start()

    def update_metrics(self):
        cur_time  = time.time()
        if cur_time - self.last_call_time < self.reuse_time:
            return

        m = Metrics()
        metrics, instance_metrics = m.get_and_aggregate_metrics()

        with self.lock:
            if metrics and instance_metrics:
                self.last_metrics["metrics"] = metrics
                self.last_metrics["instance_metrics"] = instance_metrics
                self.last_call_time = cur_time

    def update_metrics_thread(self):
        stop_event = threading.Event()
        while not stop_event.is_set():
            self.update_metrics()
            time.sleep(1)


    def prometheus_instance_metrics_handler(self):
        with self.lock:
            instance_metrics = self.last_metrics["instance_metrics"]
        return instance_metrics

    def prometheus_metrics_handler(self):
        with self.lock:
            metrics = self.last_metrics["metrics"]
        return metrics

